﻿using System;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web.Script.Serialization;

namespace ExpressesClass.DepponApi.Base
{
    public class DepponClient
    {
        string appKey;
        string companyCode;

        public DepponClient(string appKey, string companyCode)
        {
            this.appKey = appKey;
            this.companyCode = companyCode;
        }
        public T execute<T>(DepponRequest Request) where T : DepponResponse
        {
            String requestUrl = Request.GetUrl();

            String timeStamp = getTimeStamp();

            JavaScriptSerializer j = new JavaScriptSerializer();

            String _params = j.Serialize(Request);

            String digest = getDigest(_params + appKey + timeStamp);

            StringBuilder sbf = new StringBuilder();

            sbf.Append("digest=" + digest);
            sbf.Append("&timestamp=" + timeStamp);
            sbf.Append("&params=" + _params);
            sbf.Append("&companyCode=" + companyCode);

            string response = HttpPost(requestUrl, sbf.ToString());
            return response == null ? null : (T)Request.makeResponse(response);
        }

        public String getDigest(String plainText)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] dataHash = md5.ComputeHash(Encoding.UTF8.GetBytes(plainText));
            StringBuilder sb = new StringBuilder();
            foreach (byte b in dataHash)
            {
                sb.Append(b.ToString("x2").ToLower());
            }
            Console.WriteLine(sb.ToString());
            return Convert.ToBase64String(System.Text.Encoding.GetEncoding("utf-8").GetBytes(sb.ToString()));
        }

        public String getTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            string ret = string.Empty;
            ret = Convert.ToInt64(ts.TotalMilliseconds).ToString();
            return ret;
        }

        public static string MD5ToBase64String(string str)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] MD5 = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str));//MD5(注意UTF8编码)
            string result = Convert.ToBase64String(MD5, 0, 16);//Base64
            return result;
        }

        public string HttpPost(string Url, string postDataStr)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

            byte[] bs = Encoding.UTF8.GetBytes(postDataStr);

            using (Stream reqStream = request.GetRequestStream())
            {
                reqStream.Write(bs, 0, bs.Length);
                reqStream.Close();
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string encoding = response.ContentEncoding;
            if (encoding == null || encoding.Length < 1)
            {
                encoding = "UTF-8"; //默认编码  
            }
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
            string data = reader.ReadToEnd();
            return data;
        }
    }
}
